package net.chenlin.dp.ids.server.manager.impl;

import net.chenlin.dp.ids.common.constant.IdsConst;
import net.chenlin.dp.ids.common.entity.SessionData;
import net.chenlin.dp.ids.common.entity.TicketValidateResultDTO;
import net.chenlin.dp.ids.common.util.CommonUtil;
import net.chenlin.dp.ids.common.util.CookieUtil;
import net.chenlin.dp.ids.common.util.RandomKeyUtil;
import net.chenlin.dp.ids.server.config.PassportServerConfig;
import net.chenlin.dp.ids.server.manager.LoginManager;
import net.chenlin.dp.ids.server.manager.SessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录manager
 * @author zcl<yczclcn@163.com>
 */
@Component("loginManager")
public class LoginManagerImpl implements LoginManager {

    @Autowired
    private SessionManager sessionManager;

    @Autowired
    private PassportServerConfig serverConfig;

    /**
     * 登录：web
     * @param response
     * @param sessionData
     * @return
     */
    @Override
    public String login(HttpServletResponse response, SessionData sessionData) {
        String ticket = RandomKeyUtil.nextKey();
        String sessionId = RandomKeyUtil.nextKey().toLowerCase();
        // redis保存session
        sessionManager.save(sessionId, sessionData);
        // cookie保存authId
        CookieUtil.set(response, serverConfig.getAuthIdCookieName(), sessionId,
                serverConfig.getCookieDomain(), sessionData.getRememberMe());
        // 保存ticket与redis-session对应关系
        sessionManager.saveTicket(ticket, IdsConst.LOGIN_TYPE_WEB, sessionId);
        return ticket;
    }

    /**
     * 登录校验：web
     * @param request
     * @return
     */
    @Override
    public String loginCheck(HttpServletRequest request) {
        String sessionId = getSessionId(request);
        SessionData sessionData = loginCheck(sessionId, IdsConst.LOGIN_TYPE_WEB);
        if (sessionData != null) {
            String ticket = RandomKeyUtil.nextKey();
            sessionManager.saveTicket(ticket.toLowerCase(), IdsConst.LOGIN_TYPE_WEB, sessionId);
            return ticket;
        }
        return null;
    }

    /**
     * 登录校验：app
     * @param sessionId
     * @return
     */
    @Override
    public SessionData loginCheck(String sessionId) {
        return loginCheck(sessionId, IdsConst.LOGIN_TYPE_APP);
    }

    /**
     * ticket校验：app
     * @param ticket
     * @return
     */
    @Override
    public TicketValidateResultDTO ticketCheck(String ticket) {
        return sessionManager.validateTicket(ticket, IdsConst.LOGIN_TYPE_APP);
    }

    /**
     * 登出：app
     * @param sessionId
     */
    @Override
    public void logout(String sessionId) {
        sessionManager.remove(sessionId, IdsConst.LOGIN_TYPE_APP);
    }

    /**
     * 登出：web
     * @param request
     * @param response
     */
    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        String sessionId = getSessionId(request);
        // 删除sessionData
        if (CommonUtil.strIsNotEmpty(sessionId)) {
            sessionManager.remove(sessionId, IdsConst.LOGIN_TYPE_WEB);
        }
        // 删除cookie
        CookieUtil.remove(request, response, serverConfig.getAuthIdCookieName(), serverConfig.getCookieDomain());
    }

    /**
     * 登录：app
     * @param sessionData
     * @return
     */
    @Override
    public Map<String, String> login(SessionData sessionData) {
        Map<String, String> token = new HashMap<>(1);
        String ticket = RandomKeyUtil.nextKey();
        String sessionId = RandomKeyUtil.nextKey().toLowerCase();
        // redis保存session
        sessionManager.save(sessionId, sessionData);
        sessionManager.saveTicket(ticket, IdsConst.LOGIN_TYPE_APP, sessionId);
        token.put(IdsConst.TICKET_KEY, ticket);
        return token;
    }

    /**
     * 从cookie读取sessionId
     * @param request
     * @return
     */
    private String getSessionId(HttpServletRequest request) {
        return CookieUtil.getVal(request, serverConfig.getAuthIdCookieName());
    }

    /**
     * 登录校验
     * @param sessionId
     * @param loginType
     * @return
     */
    private SessionData loginCheck(String sessionId, Integer loginType) {
        if (CommonUtil.strIsNotEmpty(sessionId)) {
            return sessionManager.get(sessionId, loginType);
        }
        return null;
    }

}
